package cn.net.lwj.common.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

public class FileUtil {

    private Logger log = Logger.getLogger("ccc");


    //路径分割符
    public static String getPathSep(String path) {
        return path.contains("/") ? "/" : "\\";
    }
    /**
     * 根据路径创建一系列的目录
     *
     * @param path 完整路径
     * @return 是否成功
     */
    public static boolean mkDirectory(String path) {
        File file = null;
        try {
            file = new File(path);
            if (!file.exists()) {
                return file.mkdirs();
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return false;
    }

    //读取文件
    public static String readFile(String path) {
        try {
            File file = new File(path);
            if (!file.exists() || file.isDirectory())
                throw new FileNotFoundException();
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
            String temp = null;
            StringBuffer sb = new StringBuffer();
            temp = br.readLine();
            while (temp != null) {
                sb.append(temp).append(" ");
                temp = br.readLine();
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "[]";
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName 要删除的文件的文件名  路径加文件名:/test/aaa.txt
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) throws Exception {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            return file.delete();
        } else {
            return false;
        }
    }


    /**
     * 清空目录,包含当前目录  包含文件和文件夹  递归删除
     *
     * @param path F:\ftpFile
     * @param delCurrent false:不删除顶层目录 只清空子目录
     */
    public static void emptyDir(String path, Boolean delCurrent) {
        File file = new File(path);
        //f.delete()只能删除空目录和文件,如果目录下有文件的话就不能删除
        if (file.exists()) {
            if (file.isDirectory()) {//目录
                File[] files = file.listFiles();
                if (files != null) {
                    for (File f : files) {
                        emptyDir(f.getPath(), true);
                    }
                }
            }
            if (delCurrent) {
                file.delete();
            }
        } else {
            System.err.println("根据当前路径【" + path + "】未获取到文件!");
        }
    }

    /**
     * 只删除空文件夹
     * @param path F:\ftpFile
     */
    public static void delEmptyDir(String path) {
        File file = new File(path);
        //f.delete()只能删除空目录和文件,如果目录下有文件的话就不能删除
        if (file.exists()) {
            if (file.isDirectory()) {//目录
                if (!file.delete()) {
                    System.out.println(path + "文件夹未能删除!");
                }
            }
        }
    }

    /**
     * 只删除空文件夹  递归删除所有此路径下所有空文件夹
     * @param path F:\ftpFile
     * @param delCurrent 是否删除path顶层这个文件夹
     */
    public static void delAllEmptyDir(String path, Boolean delCurrent) {
        File file = new File(path);
        //f.delete()只能删除空目录和文件,如果目录下有文件的话就不能删除
        if (file.exists()) {
            if (file.isDirectory()) {//目录
                File[] files = file.listFiles();
                if (files != null) {
                    for (File f : files) {
                        delAllEmptyDir(f.getPath(), true);
                    }
                }
                //是否删除顶层
                if (delCurrent) {
                    file.delete();
                }
            }
        }
    }


    //基础属性
    public static void readBaseProp(String path) {
        File file = new File(path);
        File[] files = file.listFiles();
        if (files != null) {
            for (File f : files) {
                //System.out.println(f.isFile());//是否是文件
                //System.out.println(f.getPath());//读取文件路径(相对路径)
                System.out.println(f.getName());//文件名
                //System.out.println(f.getParentFile());
                //System.out.println(f.getParent());
                //System.out.println(f.getAbsolutePath());//绝对路径
                //System.out.println(f.getAbsoluteFile());//
                //System.out.println(f.exists());//是否存在
                //System.out.println(f.length());//读取文件大小(字节)
                //System.out.println(f.isHidden());//是否被隐藏
                //System.out.println(f.canRead());//是否可读
                //System.out.println(f.canWrite());//是否可写
                //System.out.println(f.isDirectory());//是否是文件夹
                System.out.println("子文件---" + Objects.requireNonNull(f.listFiles()).length);//子文件数量
                //f.delete();
            }
        }
    }





    /**
     * 是否匹配
     *
     * @param regex
     * @param input
     * @return
     */
    public static boolean matcher(String regex, String input, String msg) {
        Matcher m = Pattern.compile(regex).matcher(input);
        if (m.find()) {
            return true;
        }
        if (msg != null && !"".equals(msg)) {
            String str = msg.replace("@REPLACE@", input);
            System.err.println(str);
            String logPath = CommonProperties.UPLOADLOG + DateUtil.format(new Date(), "yyyyMMddHH") + ".txt";
            try {
                FileUtil.writeFile(logPath, str, true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public static boolean matcher(String regex, String input) {
        Matcher m = Pattern.compile(regex).matcher(input);
        if (m.find()) {
            return true;
        }
        return false;
    }

    /**
     * 获取当前目录下的文件和文件夹
     * @param path
     * @return
     */
    public static File[] getAllFiles(String path) {
        File file = new File(path);
        if (file.exists() && file.isDirectory()) {
            return file.listFiles();
        }
        return new File[0];
    }

    /**
     * 获取当前目录下(包含子目录)的文件
     * @param path 路径
     * @param list 子文件装入此list
     */
    public static void getFiles(String path, List<String> list) {
        File file = new File(path);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null) {
                    for (File f : files) {
                        getFiles(f.getPath(), list);
                    }
                }
            } else {
                //文件
                //System.out.println(file.getPath() + "----" + file.getName());
                list.add(file.getPath());
            }
        }
    }

    /**
     * 根据完整路径获取文件格式 只针对xxx.jpg   xxx.doc等文件
     * @param path
     * @return
     */
    public static String getWjgs(String path) {
        return path == null || "".equals(path) ? "" : path.substring(path.lastIndexOf(".") + 1).toLowerCase();
    }




    /**
     * 把当前路径下的子文件备份  BAK  这个空文件夹不会备份,只会备份当前文件夹有有文件的文件夹
     *
     * @param path 路径
     */
    public static void copyChildrenDir(String path) {
        try {
            File file = new File(path);
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null) {
                    for (File f : files) {
                        //下面两个方法都行
                        //copyFolder(f.getAbsolutePath(), f.getAbsolutePath() + "BAK");
                        FileUtils.copyDirectory(new File(f.getPath()), new File(f.getPath() + "BAK"));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制文件
     * @param srcPath 源路径
     * @param descPath 目标路径
     */
    public static void copyFile(String srcPath, String descPath) {
        File srcFile = new File(srcPath);
        File descFile = new File(descPath);
        //缓存区,一次性读取1024字节
        byte[] buffer = new byte[1024];
        try {
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(descFile);
            while (true) {
                //实际读取的长度是readed,有可能小于1024
                int readed = fis.read(buffer);
                //-1表示没有可读取的内容了
                if (-1 == readed) {
                    break;
                }
                fos.write(buffer, 0, readed);
                fos.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制文件夹  法一   需要引入<artifactId>commons-io</artifactId> 2.5  这个空文件夹不会备份,只会备份当前文件夹有有文件的文件夹
     * @param srcDir  原始路径 E:\\xfUploaod_ywj\\(2020)法信字第37523号
     * @param destDir 目标路径 E:\\xfUploaod_ywj\\(2020)法信字第37523号BAK
     */
    public static void copyDir(String srcDir, String destDir) {
        //FileUtils.copyDirectory(new File("E:\\xfUploaod_ywj\\(2020)法信字第37523号"), new File("E:\\xfUploaod_ywj\\(2020)法信字第37523号_bak"));
        try {
            FileUtils.copyDirectory(new File(srcDir), new File(destDir));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 复制文件夹  法二
     * @param srcPath 源路径
     * @param descPath 目标路径
     */
    public static void copyFolder(String srcPath, String descPath) {
        File srcFolder = new File(srcPath);
        File descFolder= new File(descPath);
        //源文件夹不存在
        if (!srcFolder.exists()) return;
        //目标文件夹是一个文件
        if (descFolder.isFile()) return;
        //目标文件夹不存在
        if (!descFolder.exists()) {
            //只能创建一层目录 eg:E:/test  父级必须存在
            //descFolder.mkdir();
            //可以创建多级目录 eg:E:/test/001  父级不存在的话把父级也创建了
            descFolder.mkdirs();
        }
        File[] files = srcFolder.listFiles();
        if (files != null) {
            for (File srcFile : files) {
                //在descFolder这个目录下创建文件
                File newDest = new File(descFolder, srcFile.getName());
                //是文件就直接复制
                if (srcFile.isFile()) {
                    //File newDestFile = new File(descFolder, srcFile.getName());
                    copyFile(srcFile.getAbsolutePath(), newDest.getAbsolutePath());
                }else {
                    //File newDestFolder = new File(descFolder, srcFile.getName());
                    copyFolder(srcFile.getAbsolutePath(), newDest.getAbsolutePath());
                }
            }
        }
    }

    /**
     *  向文本文件中写入内容或追加新内容,如果append为true则直接追加新内容,如果append为false则覆盖原来的内容
     * @param path E:\xfUploaod_ywj\log.txt
     * @param content 内容
     * @param append 是否追加
     * @throws IOException
     */
    public static void writeFile(String path, String content, boolean append) throws IOException {
        // 通过这个对象来判断是否向文本文件中追加内容
        File file = new File(path);
        // 如果文本文件不存在则创建它
        if (!file.exists()) {
            mkDirectory(path.substring(0, path.lastIndexOf(getPathSep(path))));
        }
        //方式一 FileOutputStream
        //FileOutputStream fw = append ? new FileOutputStream(file, true) : new FileOutputStream(file);
        //fw.write(content.getBytes(StandardCharsets.UTF_8));
        //fw.flush();
        //fw.close();
        //方式二  FileWriter
        FileWriter writer = append ? new FileWriter(path, true) : new FileWriter(path);
        writer.write(content);
        writer.close();
    }

    /**
     * 判断当前目录下是否包含文件夹
     * @param path
     * @return
     */
    public static boolean containsFolder(String path) {
        File file = new File(path);
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    if (f.isDirectory()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    //批量重命名
    public static void batchRename(String path, String baseName) {
        File file = new File(path);
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                int index = 1;
                for (File f : files) {
                    //String baseName = FilenameUtils.getBaseName(f.getAbsolutePath());
                    //String wjgs = FilenameUtils.getExtension(f.getAbsolutePath());
                    String fullPath = FilenameUtils.getFullPath(f.getAbsolutePath());
                    f.renameTo(new File(fullPath + baseName + index + ".png"));
                    index++;
                }
            }
        }
    }

    void test(){
        log.info("22222222222");
        log.info("山东省所说的");

    }

    public static void main(String[] args) throws Exception {

        new FileUtil().test();

    }


}
